#include "image.h"
#include "graphics.h"

#import "Texture2D.h"

#import <UIKit/UIKit.h>

CImage::CImage( void )
{
	m_pTexture = NULL;
}

CImage::~CImage( void )
{
	Texture2D * pTexture = (Texture2D *)m_pTexture;
	
	if( pTexture )
		[pTexture release];
}

boolean CImage::Load(uint8 * pFile,uint32 size)
{
	// load up our image
	NSData * data =[NSData alloc];
	[data initWithBytesNoCopy:pFile length:size];

	CGImageRef tempImage0 = [[[UIImage alloc] initWithData:data] CGImage];
	Texture2D * pTexture = [[Texture2D alloc] initWithCGImage:tempImage0 orientation:UIImageOrientationUp sizeToFit:false pixelFormat:/*kTexture2DPixelFormat_Automatic*/kTexture2DPixelFormat_RGBA4444];

	CGImageRelease(tempImage0);
	[data release];
	
	m_pTexture = pTexture;
	if(!m_pTexture)return FALSE;
	
	return TRUE;
}

boolean CImage::Load( const char * path )
{	
//	NSString  * sPicPath = [[NSString alloc] initWithCString:path];
    NSString *sPicPath = [[NSString alloc] initWithUTF8String:path];
	Texture2D * pTexture = [[Texture2D alloc] initWithImagePath:sPicPath];
	[sPicPath release];
	
	m_pTexture = pTexture;
	if(!m_pTexture)return FALSE;

	return TRUE;
}

boolean CImage::Load()
{
    NSString *sPicPath = @"Default.png";
	Texture2D * pTexture = [[Texture2D alloc] initWithImagePath:sPicPath];
	[sPicPath release];
	
	m_pTexture = pTexture;
	if(!m_pTexture)return FALSE;
    
	return TRUE;
}

boolean CImage::Load( CXString& path)
{
	return Load(path.Utf8String());
}

void CImage::Draw( float * vertices )
{
	Texture2D * pTexture = (Texture2D *)m_pTexture;
	[pTexture drawAtVertices:vertices];
}

void CImage::Draw2D( int16 x, int16 y,_Rect * pClip, int16 rot, float scalex, float scaley)
{	
	Texture2D * pTexture = (Texture2D *)m_pTexture;
	if(pClip == NULL)
		[pTexture drawAtPoint2D:CGPointMake( x, y ) rotate:rot scalex:scalex scaley:scaley region:CGRectMake(0,0,0,0)];
	else
		[pTexture drawAtPoint2D:CGPointMake( x, y ) rotate:rot scalex:scalex scaley:scaley region:CGRectMake(pClip->x,pClip->y,pClip->dx,pClip->dy)];
}

void CImage::Draw3D( float x, float y, float z, _Rect * pClip, int16 rotx,int16 roty,int16 rotz, float scale)
{
	Texture2D * pTexture = (Texture2D *)m_pTexture;
	if(pClip == NULL)
		[pTexture drawAtPoint3D:CGPointMake( x, y ) depth:z rotatex:rotx rotatey:roty rotatez:rotz scale:scale region:CGRectMake(0,0,0,0)];
	else
		[pTexture drawAtPoint3D:CGPointMake( x, y ) depth:z rotatex:rotx rotatey:roty rotatez:rotz scale:scale region:CGRectMake(pClip->x,pClip->y,pClip->dx,pClip->dy)];
}

void CImage::Blit( _Rect & pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY )
{
	Blit(&pClip, x, y, width, height, sourceX, sourceY);
}

void CImage::Blit( _Rect * pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY )
{
	Blit( (const _Rect *) pClip, x, y, width, height, sourceX, sourceY );
}

void CImage::Blit( const _Rect * pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY )
{	
	Texture2D * pTexture = (Texture2D *)m_pTexture;
	[pTexture blit:CGRectMake( x, y, width, height) region:CGRectMake(sourceX,sourceY,width,height) transform:0];
}

int16 CImage::GetWidth( void ) const
{
	Texture2D * pTexture = (Texture2D *)m_pTexture;

	return [pTexture contentSize].width;
}

int16 CImage::GetHeight( void ) const
{
	Texture2D * pTexture = (Texture2D *)m_pTexture;
	
	return [pTexture contentSize].height;
}

void GetTransformSettings( int transform, int * pTransform, float * pAngle )
{
	*pTransform = 0;
	*pAngle = 0;

	if( transform == 1 )
	{
		*pTransform = 2;
		*pAngle = 0;
	}
	else if( transform == 2 )
	{
		*pTransform = 1;
		*pAngle = 0;
	}
	else if( transform == 3 )
	{
		*pTransform = 0;
		*pAngle = 180;	
	}
	else if( transform == 4 )
	{
		*pTransform = 1;
		*pAngle = 270;
	}
	else if( transform == 5 )
	{
		*pTransform = 0;
		*pAngle = 270;
	}
	else if( transform == 6 )
	{
		*pTransform = 0;
		*pAngle = 90;
	}
	else if( transform == 7 )
	{
		*pTransform = 1;
		*pAngle = 90;
	}
}

void CImage::BlitTransform( _Rect & pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY, TRANSFORM_TYPE transform )
{
	BlitTransform( &pClip, x, y, width, height, sourceX, sourceY, transform);
}

void CImage::BlitTransform( _Rect * pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY, TRANSFORM_TYPE transform )
{
	BlitTransform( (const _Rect *) pClip, x, y, width, height, sourceX, sourceY, transform );
}

void CImage::BlitTransform( const _Rect * pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY, TRANSFORM_TYPE transform )
{
	Texture2D * pTexture = (Texture2D *)m_pTexture;
	
	float finalAngle;
	int finalTransform;
	GetTransformSettings(transform, &finalTransform, &finalAngle);
	
	if( finalAngle == 0 )
		[pTexture blit:CGRectMake( x, y, width, height) region:CGRectMake(sourceX,sourceY,width,height) transform:finalTransform];
	else [pTexture blit:CGRectMake( x, y, width, height) region:CGRectMake(sourceX,sourceY,width,height) transform:finalTransform angle:finalAngle];
}

void CImage::BlitTransformEx( _Rect & pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY, TRANSFORM_TYPE transform, uint32 alpha)
{
	BlitTransformEx(&pClip, x, y, width, height, sourceX, sourceY, transform, alpha);
}

void CImage::BlitTransformEx( _Rect * pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY, TRANSFORM_TYPE transform, uint32 alpha)
{
	BlitTransformEx((const _Rect*)pClip, x, y, width, height, sourceX, sourceY, transform, alpha);
}

void CImage::BlitTransformEx( const _Rect * pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY, TRANSFORM_TYPE transform, uint32 alpha)
{
	Texture2D * pTexture = (Texture2D *)m_pTexture;
	
	float finalAngle;
	int finalTransform;
	GetTransformSettings(transform, &finalTransform, &finalAngle);
	
	float finalAlpha = (float)(alpha) / 255.0;
	[pTexture blit:CGRectMake( x, y, width, height) region:CGRectMake(sourceX,sourceY,width,height) transform:finalTransform angle:finalAngle alpha:finalAlpha];
}

void CImage::BlitComplexTransform( _Rect & pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY, TRANSFORM_TYPE transform, float angle, float scale )
{
	BlitComplexTransform(&pClip, x, y, width, height, sourceX, sourceY, transform, angle, scale);
}

void CImage::BlitComplexTransform( _Rect * pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY, TRANSFORM_TYPE transform, float angle, float scale )
{
	BlitComplexTransform( (const _Rect *) pClip, x, y, width, height, sourceX, sourceY, transform, angle, scale );
}

void CImage::BlitComplexTransform( const _Rect * pClip, int16 x, int16 y, int16 width, int16 height, int16 sourceX, int16 sourceY, TRANSFORM_TYPE transform, float angle, float scale )
{
	Texture2D * pTexture = (Texture2D *)m_pTexture;
	
	float finalAngle;
	int finalTransform;
	GetTransformSettings(transform, &finalTransform, &finalAngle);
	
	finalAngle += angle;
	
	float scaleWidth = width * scale;
	float scaleHeight = height * scale;
	
	CGRect dest = CGRectMake( x, y, scaleWidth, scaleHeight );
	
	if( finalAngle == 0 || finalAngle == 360 )
		[pTexture blit:dest region:CGRectMake(sourceX,sourceY,width,height) transform:finalTransform];
	else [pTexture blit:dest region:CGRectMake(sourceX,sourceY,width,height) transform:finalTransform angle:finalAngle];
}
